package juc

import kotlinx.coroutines.*

class TaskProcessor {
    // 自定义作用域配置
//    private val processorScope = CoroutineScope(Dispatchers.Default)
    private val processorScope =
        CoroutineScope(
            SupervisorJob() +
                    Dispatchers.Default +
                    CoroutineExceptionHandler { _, e ->
                        println("[ERROR] 处理器异常: ${e.message}")
                    }
        )

    private var activeJobs = 0

    fun processTasks(taskCount: Int) {
        repeat(taskCount) { id ->
            activeJobs++
            processorScope.launch(CoroutineName("Task-$id")) {
                try {
                    println("任务 $id 开始 (${Thread.currentThread().name})")
                    val result = executeTask(id)
                    println("任务 $id 完成: $result")
                } catch (e: CancellationException) {
                    println("任务 $id 被取消")
                } finally {
                    activeJobs--
                }
            }
        }
    }

    private suspend fun executeTask(id: Int): String {
        // 模拟不同类型任务
        return when (id % 3) {
            0 -> { // CPU密集型
                withContext(Dispatchers.Default) {
                    (1..1_000_000).sum().toString()
                }
            }

            1 -> { // IO密集型
                withContext(Dispatchers.IO) {
                    delay(500) // 模拟网络请求
                    "IO-Result"
                }
            }

            else -> { // 可能失败的任务
                delay(300)
                if (id % 5 == 0) throw RuntimeException("任务 $id 模拟失败")
                "Success"
            }
        }
    }

    suspend fun waitForCompletion() {
        // 等待所有任务完成
        while (activeJobs > 0) {
            delay(100)
        }
    }

    fun shutdown() {
        println("关闭处理器...")
        processorScope.cancel("正常关闭")
    }
}

fun main() = runBlocking {
    val processor = TaskProcessor()

    // 处理10个任务
    processor.processTasks(10)

    // 等待2秒
    delay(2000)

    // 关闭前等待完成
    processor.waitForCompletion()
    processor.shutdown()

    println("应用退出")
}